import time
import math

width = 50
speed = 0.01


# Constant
def linear(x):
    return x


# speeds up
def earlyPause(x):
    return x - (1 - math.sin(x * math.pi * 2 + math.pi / 2)) / 8


# slows down
def latePause(x):
    return x + (1 - math.sin(x * math.pi * 2 + math.pi / 2)) / 8


# constant
def slowWavy(x):
    return x + math.sin(x * math.pi * 5) / 20


# constant
def fastWavy(x):
    return x + math.sin(x * math.pi * 20) / 80


# speeds up
def power(x):
    return (x + (1 - x) * 0.03) ** 2


# slows down
def inversePower(x):
    return 1 + (1 - x) ** 2


# speeds up
def fastPower(x):
    return (x + (1 + x) / 2) ** 8


# slows down
def inverseFastPower(x):
    return 1 - (1 - x) ** 3


def progressType(fun, string):
    start = time.perf_counter()
    for i in range(width + 1):
        a = '=' * i
        c = i / width
        dur = time.perf_counter() - start
        b = '_' * (width - int(fun(i)))
        print("\r{}{:^4.0%}[{}{}]{:.2f}s".format(string.center(20), c, a, b, dur), end="")
        time.sleep(speed)
    print()


progressType(linear, "Linear:")
progressType(earlyPause, "Early Pause:")
progressType(latePause, "Late Pause:")
progressType(slowWavy, "Slow Wavy")
progressType(fastWavy, "Fast Wavy")
progressType(power, "Power")
progressType(inversePower, "Inverse Power")
progressType(fastPower, "Fast Power")
progressType(inverseFastPower, "Inverse Fast Power")
